using System;
using System.Collections.Generic;
using System.Dynamic;
using RimWorld;
using Verse;

namespace RimZombieGirl
{

    public class DeadNotDead : GeneExt, IGeneChangeListener
    {
        const float defaultDownPerCheck = 0.0025f; // 默认冥血下降影响因子（每600个Tick下降量）
        // 当前僵尸等级
        private int levelCurrent = 0;

        // 进化分支
        private string branch = "";


        // 当前冥血质
        private float bloodCurrent;
        private float bloodLimit = 0f;
        
        private int lastCheckTick = -9999;

        public float BloodPercent
        {
            get
            {
                if (BloodLimit <= 0f) return 0f;
                return BloodCurrent / BloodLimit;
            }
        }

        public float BloodCurrent
        {
            get { return bloodCurrent; }
            set { bloodCurrent = Math.Max(0, Math.Min(value, BloodLimit)); }
        }
        public float BloodLimit
        {
            get { return bloodLimit; }
            set { bloodLimit = Math.Max(0f, value); }
        }

        public void UpgradeToNextLevel(String branch = "")
        { 
            if (!this.pawn?.UpgradeZombieLevel() == false)//if (!this.pawn?.UpgradeZombieLevel(levelCurrent, branch) == false)
            {
                Log.Error("Failed to upgrade zombie level for pawn: " + this.pawn?.NameShortColored.ToString());
            }
        }

        public void SaveLevelInfo(RI_ZombieLevelDef level)
        {
            levelCurrent = level.level;
            branch = level.branch;
        }

        public override void Notify_IngestedNutrition(Thing thing, float nutrition)
        {
            base.Notify_IngestedNutrition(thing, nutrition);

            bloodCurrent += (int)(nutrition * 10f);
            if (bloodCurrent > BloodLimit)
            {
                bloodCurrent = BloodLimit;
            }
        }

        public override void PostMake()
        {
            base.PostMake();
            bloodCurrent = 30; // 初始冥血质
        }

        public override void PostAdd()
        {
            base.PostAdd();
            DeadNotDeadCache.cache[pawn] = this;

            // 初始化僵尸等级
            if (levelCurrent <= 0)
            {
                if (!this.pawn.UpgradeZombieLevel())//if (!this.pawn?.UpgradeZombieLevel(1, "") == false)
                {
                    Log.Error("Failed to initialize zombie level for pawn: " + this.pawn?.NameShortColored.ToString());
                }
            }
        }

        public bool Notify_OnGeneChange(Gene gene, int action)
        {
            if (action < 0)
            {
                if (gene.def.defName == this.def.defName)
                {
                    return false; // 阻止移除本基因
                }
            }


            return true;
        }

        public override void TickInterval(int delta)
        {
            base.TickInterval(delta);

            OnIntervalPassed(pawn, delta);

            // 每600tick检查判断一次冥血下降
            if (Find.TickManager.TicksGame - lastCheckTick > 600)
            {
                var downRate = pawn.GetStatValue(ZombieDefOf.RI_Zombie_Stat_BloodDown_Percent, true);
                bloodCurrent -= defaultDownPerCheck * downRate;
            }
        }

        public void OnIntervalPassed(Pawn pawn, int interval)
        {
            // 处理僵尸饿了
            if (pawn.needs != null && pawn.needs.food.CurLevel <= 0f)
            {
                HealthUtility.AdjustSeverity(pawn, RIHediffDefOf.RI_MeatHunger, interval * 0.00090000004f);
            }
            else
            {
                HealthUtility.AdjustSeverity(pawn, RIHediffDefOf.RI_MeatHunger, interval * -0.024f);
            }
        }

        public override void ExposeData()
        {
            base.ExposeData();
            Scribe_Values.Look(ref bloodCurrent, "bloodCurrent", 30);
            Scribe_Values.Look(ref bloodLimit, "bloodLimit", 70f);
            Scribe_Values.Look(ref levelCurrent, "levelCurrent", 0);
            Scribe_Values.Look(ref branch, "branch", "");
            if (Scribe.mode == LoadSaveMode.PostLoadInit)
            {
                DeadNotDeadCache.cache[pawn] = this;
            }
        }

    }

    public static class DeadNotDeadCache
    {
        public static Dictionary<Pawn, DeadNotDead> cache = new Dictionary<Pawn, DeadNotDead>();

        public static void Clear()
        { 
            cache.Clear();
        }
    }
}